package com.example.fitnessservice.service.impl;

import com.example.fitnessservice.api.exception.CourseException;
import com.example.fitnessservice.module.dao.coachmapper.CoachBalanceMapper;
import com.example.fitnessservice.module.dao.courseMapper.*;
import com.example.fitnessservice.module.dao.usermapper.UserBalanceMapper;
import com.example.fitnessservice.module.dao.usermapper.UserMapper;
import com.example.fitnessservice.module.pojo.CourseApply;
import com.example.fitnessservice.module.pojo.CourseDetails;
import com.example.fitnessservice.module.pojo.CourseDetailsCamp;
import com.example.fitnessservice.module.pojo.CourseOrderDetails;
import com.example.fitnessservice.module.utils.GenerateOrderNo;
import com.example.fitnessservice.module.utils.TimeUtils;
import com.example.fitnessservice.service.EnterForCampService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * @author feng
 * @version 1.0
 * @&#064;description: TODO
 * @&#064;date 2022/11/26 14:46
 */
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class EnterForCampServiceImpl implements EnterForCampService {
    @Autowired
    CampCourseMapper campCourseMapper;
    private final double COACH_INCOME = 0.9;
    @Autowired
    CourseOrderMapper orderMapper;
    @Autowired
    UserCourseMapper userCourseMapper;
    @Autowired
    UserBalanceMapper userBalanceMapper;
    @Autowired
    CourseApplyMapper courseApplyMapper;
    @Autowired
    CoachBalanceMapper coachBalanceMapper;
    @Autowired
    CourseMapper courseMapper;
    @Autowired
    UserMapper userMapper;

    @Override
    public boolean updateCourseStatus(Date date) {
        if ((campCourseMapper.updateCourseStatus1(date) + campCourseMapper.updateCourseStatus2(date) + campCourseMapper.updateCourseStatus3(date)) <= 0) {

            throw new CourseException("更新数据失败");
        }
        return true;
    }

    @Override
    public boolean submitApplication(String reason, Integer campCourseId, Integer userId) {

        List<Integer> list = campCourseMapper.findCoachId(campCourseId);
        if (CollectionUtils.isEmpty(list)) {
            throw new CourseException("获取教练id失败");

        }
        CourseApply apply = new CourseApply();
        apply.setApplyTime(new Date());
        apply.setApplyUserId(userId);
        apply.setApplyCourseId(campCourseId);
        apply.setApplyReason(reason);
        apply.setApplyIfAlready(0);
        apply.setApplyCoachId(list.get(0));
        if (courseApplyMapper.submitApplication(apply) <= 0) {
            throw new CourseException("发送申请失败");
        } else if (userCourseMapper.updateCourseStatus(campCourseId, userId, 5) <= 0) {
            throw new CourseException("退课状态修改失败");
        } else if (orderMapper.updataOrderStatus(campCourseId, userId, 5) <= 0) {
            throw new CourseException("订单状态修改失败");
        }
        return true;
    }

    @Override
    public boolean join(Integer userId, Integer campCourseId, Integer courseCampIf) {
        /*
        此服务只针对训练营选课
         */
        if (courseCampIf == 0) {
            return false;
        }
        /*
        获取当前课程号所有的课程
         */
        if(orderMapper.getCourseInfo(userId, campCourseId, courseCampIf) != null){
            throw new CourseException("已选择该课程");
        }
        List<CourseDetailsCamp> courseList = campCourseMapper.findCourseDetailsById(campCourseId);

        List<CourseDetails> getCourseDetailsByUserId = userMapper.findUserCourse(userId);

        List<CourseDetailsCamp> userCamp = userMapper.findUserCamp(userId);
        for (CourseDetails courseDetails : getCourseDetailsByUserId) {
            for (CourseDetailsCamp camp : courseList) {
                if (courseDetails.getCourseStartTime().compareTo(camp.getCourseStartTime()) <= 0 && courseDetails.getCourseEndTime().compareTo(camp.getCourseStartTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
                if (courseDetails.getCourseStartTime().compareTo(camp.getCourseEndTime()) <= 0 && courseDetails.getCourseEndTime().compareTo(camp.getCourseEndTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
            }

        }
        for (CourseDetailsCamp courseDetailsCamp : userCamp) {
            for (CourseDetailsCamp camp : courseList) {

                if (courseDetailsCamp.getCourseStartTime().compareTo(camp.getCourseStartTime()) <= 0 && courseDetailsCamp.getCourseEndTime().compareTo(camp.getCourseStartTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
                if (courseDetailsCamp.getCourseStartTime().compareTo(camp.getCourseEndTime()) <= 0 && courseDetailsCamp.getCourseEndTime().compareTo(camp.getCourseEndTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
            }
        }
        if (this.latestTimeLimit(campCourseId)) {
            throw new CourseException("开课前五分钟不允许选课");
        }
        List<CourseDetailsCamp> courseDetailsCampList = campCourseMapper.findCourseDetailsById(campCourseId);
        if (CollectionUtils.isEmpty(courseDetailsCampList)) {
            return false;
        }
        /*
        课程量已满不能再选课
         */
        CourseDetailsCamp courseDetailsCamp = courseDetailsCampList.get(0);
        if (courseDetailsCamp.getCourseNum() >= 20) {
            return false;
        }
        CourseOrderDetails courseOrderDetails = new CourseOrderDetails();
        Date date = new Date();
        courseOrderDetails.setOrderTime(date);
        courseOrderDetails.setOrderCourseId(campCourseId);
        courseOrderDetails.setOrderUserId(userId);
        courseOrderDetails.setOrderStatus(2);
        courseOrderDetails.setOrderMoney(courseDetailsCamp.getCourseMoney());
        courseOrderDetails.setOrderNo(GenerateOrderNo.generateOrderNo(userId, campCourseId));
        courseOrderDetails.setOrderCampIf(courseCampIf);
        courseOrderDetails.setOrderCoachId(courseDetailsCamp.getCourseCoachId());
        if (userCourseMapper.join(userId, campCourseId, courseCampIf) <= 0) {
            throw new CourseException("课程添加失败");
        } else if (campCourseMapper.campNumAdd(campCourseId) <= 0) {
            throw new CourseException("课程容量扣减失败");
        } else if (orderMapper.generateOrder(courseOrderDetails) <= 0) {
            throw new CourseException("订单生成失败");
        } else if (userBalanceMapper.userSpend(courseDetailsCamp.getCourseMoney(), userId) <= 0) {
            throw new CourseException("余额扣除失败");
        }
        return true;
    }

    @Override
    public boolean getCourseInfo(Integer userId, Integer courseId, Integer courseCampIf) {

        List<CourseDetailsCamp> courseList = campCourseMapper.findCourseDetailsById(courseId);
        List<CourseDetails> getCourseDetailsByUserId = userMapper.findUserCourse(userId);
        List<CourseDetailsCamp> userCamp = userMapper.findUserCamp(userId);
        for (CourseDetails courseDetails : getCourseDetailsByUserId) {
            for (CourseDetailsCamp camp : courseList) {
                if (courseDetails.getCourseStartTime().compareTo(camp.getCourseStartTime()) <= 0 && courseDetails.getCourseEndTime().compareTo(camp.getCourseStartTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
                if (courseDetails.getCourseStartTime().compareTo(camp.getCourseEndTime()) <= 0 && courseDetails.getCourseEndTime().compareTo(camp.getCourseEndTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
            }
        }
        for (CourseDetailsCamp courseDetailsCamp : userCamp) {
            for (CourseDetailsCamp camp : courseList) {
                if (courseDetailsCamp.getCourseStartTime().compareTo(camp.getCourseStartTime()) <= 0 && courseDetailsCamp.getCourseEndTime().compareTo(camp.getCourseStartTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
                if (courseDetailsCamp.getCourseStartTime().compareTo(camp.getCourseEndTime()) <= 0 && courseDetailsCamp.getCourseEndTime().compareTo(camp.getCourseEndTime()) >= 0) {
                    throw new RuntimeException("时间冲突不能选课");
                }
            }
        }
        /*
        已选择课程
         */
        return orderMapper.getCourseInfo(userId, courseId, courseCampIf) != null;
    }

    /*
        查询训练营列表最早的开课时间，然段当前时间是否允许选课，true允许选课
        限制开课前五分钟不能选课
        true，当前时间+5>开课时间，不允许选课
        */
    @Override
    public boolean latestTimeLimit(Integer courseId) {

        List<CourseDetailsCamp> courseDetailsById = campCourseMapper.findCourseDetailsById(courseId);
        if (CollectionUtils.isEmpty(courseDetailsById)) {
            throw new CourseException("没有该门课程");
        }
        CourseDetailsCamp courseDetailsCamp = courseDetailsById.get(0);
        Date firstStartTime = courseDetailsCamp.getCourseStartTime();
        for (CourseDetailsCamp camp : courseDetailsById) {
            if (firstStartTime.compareTo(camp.getCourseStartTime()) > 0) {
                firstStartTime = camp.getCourseStartTime();
            }
        }
        Date date = new Date();
        Date latestTime = TimeUtils.addMinutes(date, 5);
        return latestTime.compareTo(firstStartTime) > 0;
    }

    @Override
    public boolean whetherApply(Integer courseId) {

        List<CourseDetailsCamp> courseDetailsById = campCourseMapper.findCourseDetailsById(courseId);
        if(CollectionUtils.isEmpty(courseDetailsById)){
            throw new CourseException("没有该门课程");
        }
        CourseDetailsCamp courseDetailsCamp = courseDetailsById.get(0);
        Date firstStartTime = courseDetailsCamp.getCourseStartTime();
        for (CourseDetailsCamp camp : courseDetailsById) {
            if (firstStartTime.compareTo(camp.getCourseStartTime()) > 0) {
                firstStartTime = camp.getCourseStartTime();
            }
        }
        Date date = new Date();
        Date latestDropTime = TimeUtils.addMinutes(firstStartTime, -120);
        return date.compareTo(latestDropTime) < 0;
    }
/*
退课
 */
    @Override
    public boolean cancelCourse(Integer userId, Integer courseId, Integer courseCampIf) {
        if(!this.whetherApply(courseId)){
            throw new CourseException("不允许申请退课");
        }
        List<CourseDetailsCamp> camps = campCourseMapper.findCourseDetailsById(courseId);
        if(CollectionUtils.isEmpty(camps)){
            throw new CourseException("没有该门课程");
        }
        CourseDetailsCamp camp=camps.get(0);
        if (userCourseMapper.cancelCourse(userId, courseId, courseCampIf) <= 0) {
            throw new CourseException("修改用户课程状态失败");
        } else if (campCourseMapper.campNumReduce(courseId) <= 0) {
            throw new CourseException("课容量数据增加失败");
        } else if (orderMapper.cancelOrderstatus(userId, courseId, courseCampIf) <= 0) {
            throw new CourseException("订单状态修改失败");
        } else if (userBalanceMapper.userReturn(camp.getCourseMoney(), userId) <= 0) {
            throw new CourseException("更新用户金额失败");
        }
        return true;
    }
    /*
           是否符合申请时间非训练营退课需求，开课前两小时可以退课，否则不能退课,true允许退课
            */
    @Override
    public Integer getCourseQuantity(Integer campCourseId) {
        List<CourseDetailsCamp> courseDetailsCampList = campCourseMapper.findCourseDetailsById(campCourseId);
        if(CollectionUtils.isEmpty(courseDetailsCampList)){
            throw new CourseException("没有该门课程");
        }
        CourseDetailsCamp courseDetailsCamp = courseDetailsCampList.get(0);
        return 20 - courseDetailsCamp.getCourseNum();
    }

    @Override
    public List<CourseApply> getPersonalApplyStatus(Integer userId, Integer applyStatus) {
        List<CourseApply> applyList = courseApplyMapper.getPersonalApplyStatus(userId, applyStatus);
        if (CollectionUtils.isEmpty(applyList)) {
            return null;
        }
        return applyList;
    }

    @Override
    public boolean returnMoney(Integer applyId, Integer campCourseId, Integer userId) {
        CourseApply courseApply = courseApplyMapper.getOneApplyById(applyId);
        if(courseApply==null){
            throw new RuntimeException("没用该申请");
        }
        double bd;
        if (courseApply.getApplyIfAlready() == 3) {
            throw new RuntimeException("你已经退款了");
        } else if (courseApply.getApplyIfAlready() == 2) {
            bd = 1.0;
        } else {
            bd = 0.5;
        }
        List<CourseDetailsCamp> list = campCourseMapper.findCourseDetailsById(campCourseId);
        if(CollectionUtils.isEmpty(list)){
            throw new RuntimeException("没有该课程");
        }
        List<CourseDetailsCamp> surplusList = campCourseMapper.findCourseDetailsByIdAndTime(campCourseId, courseApply.getApplyTime());
        double total = list.get(0).getCourseMoney();
        double shouldReturn = total * surplusList.size() / list.size();
        if(userBalanceMapper.userReturn(shouldReturn * bd, userId)<=0){
            throw new RuntimeException("退还金额失败");
        }else if (!CollectionUtils.isEmpty(surplusList)
                && coachBalanceMapper.coachGetMoney(COACH_INCOME * total * ((list.size() - surplusList.size()) / (list.size() * 1.0)), list.get(0).getCourseCoachId()) <= 0) {
            throw new RuntimeException("教练余额增长失败");
        } else if (userCourseMapper.updateCourseStatus(campCourseId, userId, 6) <= 0) {
            throw new CourseException("退课状态修改失败");
        } else if (orderMapper.updataOrderStatus(campCourseId, userId, 6) <= 0) {
            throw new CourseException("订单状态修改失败");
        } else if (courseApplyMapper.updateApplyStatus(applyId) <= 0) {
            throw new CourseException("申请状态修改失败");
        }
        return true;
    }


}
